package com.damai.crypt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class BaseRsa implements IRsa {

	private String signAlgorithms;

	public BaseRsa(String signAlgorithms) {
		this.signAlgorithms = signAlgorithms;
	}

	
	@Override
	public boolean verify(byte[] data, byte[] sign, byte[] publicKey) throws CryptException {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));

			java.security.Signature signature = java.security.Signature.getInstance(signAlgorithms);

			signature.initVerify(pubKey);
			signature.update(data);
			return signature.verify(sign);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public byte[] decrypt(byte[] data, byte[] privateKey) throws CryptException {
		try {
			PrivateKey prikey = getPrivateKey(privateKey);

			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, prikey);

			InputStream ins = new ByteArrayInputStream(data);
			ByteArrayOutputStream writer = new ByteArrayOutputStream();
			// rsa解密的字节大小最多是128，将需要解密的内容，按128位拆开解密
			byte[] buf = new byte[128];
			int bufl;

			while ((bufl = ins.read(buf)) != -1) {
				byte[] block = null;

				if (buf.length == bufl) {
					block = buf;
				} else {
					block = new byte[bufl];
					for (int i = 0; i < bufl; i++) {
						block[i] = buf[i];
					}
				}

				writer.write(cipher.doFinal(block));
			}

			return writer.toByteArray();
		} catch (Exception e) {
			throw new CryptException(e);
		}

	}

	private PrivateKey getPrivateKey(byte[] privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(keySpec);
	}

	@Override
	public byte[] encrypt(byte[] data, byte[] publicKey) throws CryptException {
		try{
			PublicKey pubKey = getPublicKey(publicKey);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);
			byte[] output = cipher.doFinal(data);  
            return output;
		}catch(Exception e){
			throw new CryptException(e);
		}
		
		
	}

	private PublicKey getPublicKey(byte[] publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(keySpec);
	}

	@Override
	public byte[] sign(byte[] data, byte[] privateKey) throws CryptException {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(privateKey);
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
			java.security.Signature signature = java.security.Signature.getInstance(signAlgorithms);
			signature.initSign(priKey);
			signature.update(data);
			byte[] signed = signature.sign();
			return signed;
		} catch (Exception e) {
			throw new CryptException(e);
		}

	}


	@Override
	public KeyPair generateKeyPair(int keySize) throws CryptException {
		return null;
	}

}
